package com.nut.api.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nut.api.req.LoginReq;
import com.nut.api.resp.UserInfoResp;
import com.nut.common.Holder;
import com.nut.common.RedisKeys;
import com.nut.common.Result;
import com.nut.config.LoginProperties;
import com.nut.config.RsaProperties;
import com.nut.entity.SysUser;
import com.nut.enums.CodeTypeEnum;
import com.nut.interceptor.JwtTokenUtil;
import com.nut.interceptor.UserJwt;
import com.nut.mapper.SysUserMapper;
import com.nut.mapper.SysUserRoleMapper;
import com.nut.service.SysUserService;
import com.nut.util.RsaUtils;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/admin/auth/")
public class AuthController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ValueOperations<String, Object> valueOperations;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private LoginProperties loginProperties;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostMapping("/login")
    public Result login(@RequestBody LoginReq loginReq) throws Exception {

        // 密码解密
        String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, loginReq.getPassword());

        String username = loginReq.getUsername();

        String imgCodeKey = RedisKeys.getImgCodeKey(loginReq.getUuid());
        Object object = valueOperations.get(imgCodeKey);
        if (object == null) {
            return Result.fail("验证码不存在或已过期");
        }
        if (!object.toString().equals(loginReq.getCode())) {
            return Result.fail("验证码错误");
        }

        redisTemplate.delete(loginReq.getUuid());

        List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        if (sysUsers.size() == 0) {
            return Result.fail("未找到用户");
        }
        if (sysUsers.size() > 1) {
            return Result.fail("找到多个用户");
        }

        SysUser sysUser = sysUsers.get(0);
        if (!passwordEncoder.matches(password, sysUser.getPassword())) {
            return Result.fail("密码错误");
        }
        if (sysUser.getStatus() == 1) {
            return Result.fail("该账号已被冻结");
        }

        Integer userId = sysUser.getId();
        UserJwt userJwt = new UserJwt();
        userJwt.setUserId(userId);
        userJwt.setUsername(username);
        userJwt.setNickname(sysUser.getNickname());
        userJwt.setDeptCode(sysUser.getDeptCode());
        if (!username.equals("admin")) {
            //如果不是超级管理员 需要获取当前用户角色信息
            List<Integer> roleIds = sysUserRoleMapper.selectByUserId(userId);
            userJwt.setRoleIds(roleIds);
        }

        String token = jwtTokenUtil.generateToken(userJwt);
        return Result.ok(token);
    }

    //获取验证码
    @GetMapping("/imgCode")
    public Result<Object> imgCode() {
        // 获取运算的结果
        Captcha captcha = loginProperties.getCaptcha();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String imgCodeKey = RedisKeys.getImgCodeKey(uuid);
        //当验证码类型为 arithmetic时且长度 >= 2 时，captcha.text()的结果有几率为浮点型
        String captchaValue = captcha.text();
        if (captcha.getCharType() - 1 == CodeTypeEnum.arithmetic.ordinal() && captchaValue.contains(".")) {
            captchaValue = captchaValue.split("\\.")[0];
        }
        System.out.println("captchaValue=" + captchaValue);
        // 保存
        valueOperations.set(imgCodeKey, captchaValue, loginProperties.getExpiration(), TimeUnit.MINUTES);
        // 验证码信息
        Map<String, String> imgResult = new HashMap<String, String>(4);
        imgResult.put("img", captcha.toBase64());
        imgResult.put("uuid", uuid);
        return Result.ok(imgResult);
    }

    private String getUuid() {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return uuid;
    }

    @GetMapping(value = "/info")
    public Result<UserInfoResp> getUserInfo() {
        UserJwt userJwt = Holder.USER_JWT_THREAD_LOCAL.get();
        Integer userId = userJwt.getUserId();
        String username = userJwt.getUsername();
        Result<UserInfoResp> userInfo = sysUserService.getUserInfo(userId, username);
        return userInfo;
    }

}
